<?php
namespace libs\qoy\Model;
use libs\qoy\DI;
use \NotORM_Result;
/**
 * ModelNotORM 基于NotORM的Model基类
 *
 * insert_multi
 * insert
 * update
 * insert_update
 * insert_id
 * delete
 * select
 * where
 * AND
 * OR
 * order
 * limit
 * group
 * lock
 * union
 * aggregation
 * count
 * min
 * max
 * sum
 * fetch
 * fetchPairs
 * rewind
 * current
 * key
 * next
 * valid
 * offsetExists
 * offsetGet
 * offsetSet
 * offsetUnset
 * jsonSerialize
 * 
 * - 我们这里对ext_data使用json而不是序列化，是为了更容易阅读、理解、测试
 * - 可重写formatExtData() & parseExtData()重新定制针对序列化LOB的转换
 * - 具体子类需要实现getTableName($id)以提供对应的表名或者分表名
 * - 对于如何寻找表主键，我们将配置中全部的表(包括分表)对应的主键进行了装配，如果觉得有性能问题，可重写getTableKey($table)；这是一个手动和自动的问题
 * @——method mixed query(string $sql, array $bind = [], boolean $fetch = false, boolean $master = false, mixed $class = false)  SQL查询
 * @——method setField($field, $value = '')
 * @——method findOrFail($data = null) 查找单条记录 如果不存在则抛出异常 
 * 
 */

abstract class ModelNotORM implements IModel {
    
    public function get( $id, $fields = '*') {
        $needFields = is_array($fields) ? implode(',', $fields) : $fields;
        
        $notorm = $this->getORM($id);
           
        $table = $this->getTableName($id);
        $rs = $notorm->select($needFields)
            ->where(DI::instance()->dbNotORM->getTableKey($table), $id)->fetch();
        
        $this->parseExtData($rs);
        $notorm->union($notorm);
        return $rs;
    }
    
    
    
    
    
    public function insert($data, $id = NULL) {
        $this->formatExtData($data);

        $notorm = $this->getORM($id);
        $notorm->insert($data);
        

        return $notorm->insert_id();
    }
    public function update($id, $data) {
        $this->formatExtData($data);
        $notorm = $this->getORM($id);
        $table = $this->getTableName($id);
        return $notorm->where(DI::instance()->dbNotORM->getTableKey($table), $id)->update($data);
    }

    public function delete($id) {
        $notorm = $this->getORM($id);

        $table = $this->getTableName($id);
        return $notorm->where($this->getTableKey($table), $id)->delete();
    }

    /**
     * 对LOB的ext_data字段进行格式化(序列化)
     */
    protected function formatExtData(&$data) {
        if (isset($data['ext_data'])) {
            $data['ext_data'] = json_encode($data['ext_data']);
        }
    }

    /**
     * 对LOB的ext_data字段进行解析(反序列化)
     */
    protected function parseExtData(&$data) {
        if (isset($data['ext_data'])) {
            $data['ext_data'] = json_decode($data['ext_data'], true);
        }
    }
    
    public function __call($name, $arguments) {
        
    }

    /**
     * 根据主键值返回对应的表名，注意分表的情况
     */
    abstract protected function getTableName($id);

    /**
     * 快速获取ORM实例，注意每次获取都是新的实例
     * @param string/int $id
     * @return NotORM_Result
     */
    protected function getORM($id = NULL) {
        
         $table = $this->getTableName($id);
         
         return DI::instance()->dbNotORM->$table;
        
    }
    
}
